import {Creep, RoomPosition, StructureSpawn} from "game/prototypes";
import Room from "./room.mjs";
import {ATTACK, CARRY, ERR_BUSY, ERR_NOT_IN_RANGE, MOVE, RANGED_ATTACK, WORK} from "game/constants";
import {army} from "../types/army.mjs";
import {Flag} from "arena/prototypes";
import {getObjectsByPrototype} from "game/utils";

/**
 * 项目名称: Screeps Arena code
 * 创建时间: 2023/9/27
 * 作者: 码力全开
 */

/**
 * 获取元素的攻击距离
 * @param creep
 * @private
 */
function getTickRange(creep:Creep){
    const body = creep.body
    let range:number = -1
    for (const item of body) {
        if (is_attack_element(item) ){
            switch (item.type) {
                case ATTACK:
                    range = 1;
                    break;
                case  RANGED_ATTACK:
                    range = 3;
                    break;
            }
        }
    }
    return range;
}

/**
 * 是否是攻击元素
 * @param body
 * @private
 */
function is_attack_element(body:Object):boolean{
    const arr = [ATTACK,RANGED_ATTACK]
    // @ts-ignore
    return arr.find(item=>item == body.type) != -1
}
/**
 * 检测自己的八个方向的敌人
 * 进行敌人的锁定和攻击
 */
function lock_enemy(creep:Creep,range:number){
    const maxX = creep.x + range
    const minX = creep.x - range
    const maxY = creep.y + range
    const minY = creep.y - range
    // 位置数组
    const position_arr = []
    for (let i = minX; i <= maxX; i++) {
        for (let j = minY; j <= maxY; j++) {
            position_arr.push([i,j])
        }
    }
    console.log(position_arr)
    // 所有的的敌人
    const enemies = getObjectsByPrototype(Creep).filter(item=>!item.my)
    // @ts-ignore
    const lockEnemyOrNot =  creep.lockEnemyOrNot
    // 如果当前锁定的有目标则不再重新锁定
    if (lockEnemyOrNot) {
        return
    }
    for (let i = 0; i < enemies.length; i++) {
        let enemy = enemies[i]
        let {x,y} = enemy
        let result =  position_arr.findIndex(item=>{
            return x == item[0] && y == item[1]
        })
        // 如果在攻击范围内就进行攻击
        if (result != -1) {
            creep.attack(enemies[i])
        }

    }


}
export class MyCreep extends Room {
    /**
     * 小兵数组
     * @private
     */
    private creepList: Creep[] = []
    /**
     * 是否创建中
     * @private
     */
    private isProduce: boolean = false

    constructor() {
        super()
    }

    public watch() {
        console.log("myCreep watch running....")
    }

    public attackEnemy() {
        let list = getObjectsByPrototype(Creep).filter(item => item.my).filter(item => item.body.find(i => i.type == ATTACK))
        const enemy = getObjectsByPrototype(StructureSpawn).find(s => !s.my) || null
        if (!enemy) return
        for (let i = 0; i < list.length; i++) {
            let item = list[i]
            if (item.attack(enemy) == ERR_NOT_IN_RANGE) {
                item.moveTo(enemy)
            }
        }
    }

    /**
     * 开启创造
     */
    public startCreate(){
        this.isProduce = true
    }




    /**
     * 检测附近是否有敌人
     */
   public defense(){

        // console.log("检测是否有敌人",this.x,this.y)
        // @ts-ignore
        let item:Creep = this
        console.log('当前位置',item)
        /**
         * 检测的算法
         * 1. 获得自己的位置坐标
         * 2. 以自己为中心 以攻击范围为检索距离
         * 3. 假如 攻击距离为1 而敌人的位置是在距离自己为2的位置则不管
         * 4. 假如敌人的攻击距离比自己的攻击距离长，先逃出敌人的攻击距离
         *      但是如果受到敌人的攻击则需要进行反击，当某个组件的血量低于一半的时候
         *      需要找到距离自己最近的一个奶妈，进行治疗
        *
         */
        let range = getTickRange(item)
        // 如果不是攻击元素就不再继续检测
        if (range == -1 ) return
        // 敌人的锁定
        lock_enemy(item,range)
    }
    /**
     * 开始创建小兵
     */
    public startCrateCreep(type: army[]) {
        if (!this.isProduce) {
            return
        }
        type = type.filter((item,index)=>{
            let residue_number = item.plan_number - item.current
            return residue_number>0
        })
        let resultArr: army[] = type.sort((a: army, b: army) => {
            let result = 0
            result = a.weight - b.weight
            if (result == 0) {
                result = (a.plan_number - a.current) - (b.plan_number - b.current)
            }
            return result
        })
        for (let i = 0; i < resultArr.length; i++) {
            let item = resultArr[i]
            let result = this.CreateCreep(item.type)
            if (result &&result.object) {
                Object.assign( result.object,{
                    // 当前是否锁定敌人
                    lockEnemyOrNot:false,
                    defense:this.defense
                } )
            }
        }
    }

    public rallyPoint(moveFlag: RoomPosition) {
        let list = getObjectsByPrototype(Creep).filter(item => item.my).filter(item => item.body.find(i => i.type == ATTACK))
        if (list.length > 6) {
            this.attackEnemy()
            return
        }
        for (let i = 0; i < list.length; i++) {
            list[i].moveTo(moveFlag)
        }
    }

    /**
     * 停止创建小兵
     */
    public stopCreateCreep() {
        this.isProduce = false
    }

    /**
     * 创建采集工种
     * create_number 创建数量
     * @constructor
     */
    public CreateGather(create_number: number, current_number: number) {
        let temp: number = current_number
        for (let i = 0; i < create_number; i++) {
            let createResult = this.CreateCreep([MOVE, MOVE, WORK, WORK, CARRY, CARRY])
            if (createResult && Boolean(createResult?.object)) {
                temp = temp + 1
            }
        }
        return temp
    }

}